/* ----------------------------------------------------------------------------------------------------------------
 * Renderer
 * ----------------------------------------------------------------------------------------------------------------
 */
package pure.engine.renderer 
{
	import flash.display.BitmapData;
	import flash.display.IBitmapDrawable;
	import flash.filters.BitmapFilter;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	
	import pure.engine.core.VisibleCore;
	import pure.engine.system.ns_despair;
	
	use namespace ns_despair;
	
	/**
	 * 抽象渲染器
	 * 
	 * @author ＃Pure
	 */
public class Renderer extends VisibleCore implements IRenderer 
{

	
	
	
	//======================
	// Property
	//======================
	
	
	// 透明度
	public function get alpha():Number { return m_alpha; }
	public function set alpha(v:Number):void 
	{
		if (m_alpha != v)
		{
			if      (v < 0)    m_alpha = 0;
			else if (v > 1)    m_alpha = 1;
			else               m_alpha = v
			
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	

	// 缩放X
	public function get scaleX():Number { return m_scaleX; }
	public function set scaleX(v:Number):void 
	{
		v = v < 0 ? 0 : v;
		if (m_scaleX != v)
		{
			m_scaleX = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}

	}
	
	
	// 缩放Y
	public function get scaleY():Number { return m_scaleY; }
	public function set scaleY(v:Number):void
	{ 
		v = v < 0 ? 0 : v;
		if (m_scaleY != v)
		{
			m_scaleY = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}

	}

	
	// 缩放Max
	// [Hint] - 普通情况，尽量不要使用该属性.
	public function get scaleMax():Number { return m_scaleMax; }
	public function set scaleMax(v:Number):void
	{ 
		if (m_scaleMax != v)
		{
			m_scaleMax = v;
			if (m_dirtyFlag > -1)  m_dirtyFlag = 2;
		}
	}

	
	// 是否可见
	override public function set visible(b:Boolean):void
	{ 
		m_visible = b;
		if (b)
		{
			m_dirtyFlag = 2;
		}
		else
		{
			m_dirtyFlag = -1;
		}
	}
	
	
	// 弧度
	override public function set angle(v:Number):void 
	{ 
		if (m_angle != v)
		{
			m_angle = v;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	// 忽略弧度
	public function get ignoreAngle():Boolean
	{ 
		return m_ignoreAngle; 
	}
	
	public function set ignoreAngle(b:Boolean):void 
	{ 
		if (m_ignoreAngle != b)
		{
			m_ignoreAngle = b;
			if (m_dirtyFlag == 0)  m_dirtyFlag = 1;
		}
	}
	
	
	
	
	/**
	 * 旋转
	 * 
	 * @param duration
	 * @param offset
	 */
	public function rotate(duration:Number, offset:Number):void
	{
		
	}
	
	/**
	 * 旋转至
	 * 
	 * @param duration       持续时间
	 * @param finalRotation  最终角度
	 * @param shortcut       是否按捷径旋转
	 */
	public function rotateTo(duration:Number, finalRotation:Number, shortcut:Boolean = true):void
	{
		
	}
	
	

	
	/* ----------------------------------------------------------------------------------------------------------------
	 * ★★★★★★★★★★★★★★★★★★★★★  private  ★★★★★★★★★★★★★★★★★★★★★
	 * ----------------------------------------------------------------------------------------------------------------
	 */
	
	

	
	// 更新
	// ===============================================
	// [Feature] 
	// -----------------------------------------------
	
	// ① visible为false(flag == -1)时，不做任何更新
	// [Hint] - 除visible变化外，改变其他状态flag无效
	// -----------------------------------------------
	
	// ② 未变化，skip...
	// [Hint] - visible为true时，初期值
	// -----------------------------------------------
	
	// ② image变化，更新画像
	// [Hint] - visible为true时，可覆盖flag(0)
	// -----------------------------------------------
	
	// ③ range变化，会先检查一次，并更新画像
	// [Hint] - visible为true时，可覆盖flag(-1，0)
	// ===============================================
	ns_despair function advance():void 
	{
		var newRange:Number;
		var i:int;
		
		if (m_dirtyFlag <= 0)  return;
		
		// 一级画像缓存
		//!!!!!!!!!!!!!!!!!!!!!!!
		_generatePrimaryImage();
		
		// 范围变化
		//!!!!!!!!!!!!!!!!!!!!!!!
		if (m_dirtyFlag == 2)
		{
			if ((newRange = m_range * m_scaleMax) != m_oldRange)
			{
				if (m_alphaMask)
				{
					m_alphaMask.dispose();
					m_alphaMask = new BitmapData(m_imageB.width, m_imageB.height);
				}
				
				if (m_imageB)  m_imageB.dispose();
				
				m_imageB    =  new BitmapData(newRange * 2, newRange * 2, true, 0x0);
				m_oldRange  =  newRange;
			}
		}

		// 二级画像缓存
		//!!!!!!!!!!!!!!!!!!!!!!!
		// Debug !!
		//m_imageB.fillRect(m_imageB.rect, 0x4000FF00);
		m_imageB.fillRect(m_imageB.rect, 0x0);
		
		// 
		if (m_angle != 0 || m_scaleX != 1 || m_scaleY != 1)
		{
			cachedMatrix.identity();
			if (m_ignoreAngle)
			{
				cachedMatrix.rotate(-m_angle);
			}
			cachedMatrix.translate(m_x, m_y);
			cachedMatrix.scale(m_scaleX, m_scaleY);
			cachedMatrix.rotate(m_angle);
			cachedColorTransform.alphaMultiplier = m_alpha;
			cachedMatrix.translate(m_oldRange, m_oldRange);
			m_imageB.draw(m_imageA, cachedMatrix, cachedColorTransform, null, null, true);
		}
		
		else
		{
			cachedPoint.x  =  m_oldRange + m_x;
			cachedPoint.y  =  m_oldRange + m_y;
			
			if (m_alpha == 1) 
			{
				m_imageB.copyPixels(m_imageA, m_imageA.rect, cachedPoint, null, null, true);
			}
			else         
			{
				if (m_oldAlpha != m_alpha)
				{
					if (!m_alphaMask)
					{
						m_alphaMask = new BitmapData(m_imageB.width, m_imageB.height);
					}
					
					m_alphaMask.fillRect(m_alphaMask.rect, int(m_alpha * 255) << 24 | 0xFFFFFF);
					m_oldAlpha = m_alpha;
				}
				m_imageB.copyPixels(m_imageA, m_imageA.rect, cachedPoint, m_alphaMask, null, true);
			}
		}

		// 滤镜
		if (m_numFilter)
		{
			for (i = 0; i < m_numFilter; i++)
			{
				m_imageB.applyFilter(m_imageB, m_imageB.rect, cachedZeroPoint, m_filterList[i]);
			}
		}
	}

	
	// 毁灭
	override ns_despair function destroy():void
	{
		super.destroy();

		m_imageA = null;
		if (m_imageB)
		{
			m_imageB.dispose();
			m_imageB = null;
		}
		if (m_alphaMask)
		{
			m_alphaMask.dispose();
			m_alphaMask = null;
		}
	}
	
	
	// internal
	// 生成一级画像缓存(m_imageA)
	protected function _generatePrimaryImage():void
	{
		// OVERRIDE !!
	}
	

	
	
	
	
	//======================
	// Member
	//======================
	

	ns_despair var m_alpha:Number = 1.0;  // 透明度

	ns_despair var m_scaleX:Number = 1.0;  // 缩放比X
	
	ns_despair var m_scaleY:Number = 1.0;  // 缩放比Y
	
	ns_despair var m_scaleMax:Number = 1.0;  // 最大缩放比(影响画像范围)

	ns_despair var m_alphaMask:BitmapData;  // copyPixels透明属性画像用.
	
	ns_despair var m_imageA:BitmapData;  // 一级画像缓存，未处理的原始画像数据缓存.

	ns_despair var m_imageB:BitmapData;  // 二级画像缓存，锁定实体中心的，处理过的输出画像.
	
	ns_despair var m_dirtyFlag:int = 2;  // 初期设定为范围变化
	
	
	
	//======================
	// Cached
	//======================
	
	
	ns_despair var m_oldAlpha:Number = 1.0;  // 记录了当前alphaMask的透明度

	ns_despair var m_oldRange:Number;  // 记录了当前的
	
	ns_despair var m_ignoreAngle:Boolean;  // 旋转时是否忽略角度(保持原角度)

	

	ns_despair static var cachedMatrix:Matrix = new Matrix();
	
	ns_despair static var cachedColorTransform:ColorTransform = new ColorTransform();
	
	
}

}